#! /bin/bash
# Xenomai application loader script.
# (Processes the .runinfo files)
# June 2004, <rpm@xenomai.org>

usage='usage: xeno-load [[dir:]target]'
prefix="@prefix@"
exec_prefix="@exec_prefix@"
insmod=/sbin/insmod
modprobe=/sbin/modprobe
rmmod=/sbin/rmmod
modext=@XENO_MODULE_EXT@
verbose=0
spc=" 	"

if test "x$1" = x--help; then
  echo $usage
  exit 0
fi

if test "x$1" = x--verbose; then
  verbose=1
  shift
fi

if test "x$1" = x--; then
  target_dir=`pwd`
  target_name=default
else
  qual_target=$1
  shift
  target_dir=`echo $qual_target|cut -d: -f1`
  target_name=`echo $qual_target|cut -s -d: -f2`
  if test "x$target_dir" = x; then
     target_dir=`pwd`
  fi
  if test "x$target_name" = x; then
     if `echo $target_dir | grep -q /`; then
        target_name=default
     else
        target_name=$target_dir
        target_dir=.
     fi
  fi
fi
if test "x$1" = x--; then
   shift
fi
cmdargs=$*

run_info_file=$target_dir/.runinfo

if test \! -r $run_info_file; then
   echo "xeno-load: cannot find run info: $run_info_file"
   exit 2
fi

if test $target_name = default; then
  target_name=`cut -s -d: -f1 $run_info_file | head -1`
  if test "x$target_name" = x; then
     echo "xeno-load: no target defined in $run_info_file"
     exit 2
  fi
fi

stanza=`grep "^[$spc]*$target_name[$spc]*:" $run_info_file`

if test "x$stanza" = x; then
   echo "xeno-load: cannot find run info for target $target_name"
   exit 2
fi


xeno_moddir=`grep "^[$spc]*xeno_moddir[$spc]*=" $run_info_file`
user_moddir=`grep "^[$spc]*user_moddir[$spc]*=" $run_info_file`

if test "x$xeno_moddir" = x; then
  eval xeno_moddir='${DESTDIR}@XENO_MODULE_DIR@'
else
  eval $xeno_moddir
fi

eval $user_moddir

if `$modprobe -nq adeos >& /dev/null`; then
   target_deps="adeos+"
else
   target_deps=
fi

target_deps="${target_deps}hal+nucleus+`echo $stanza | cut -d: -f2`"
target_info=`echo $stanza | cut -d: -f3`
target_mesg=`echo $stanza | cut -s -d: -f4`

test $verbose = 1 && echo "Running $target_name from $run_info_file"

if test \! "x`type -t sudo`" = x; then
  sudo=sudo
fi

if test \! "x$target_mesg" = x; then
  case "$target_mesg" in
  control_c)
    target_mesg="Type ^C to stop this application."
    ;;
  esac
  echo "*"
  echo "*"
  echo "* $target_mesg"
  echo "*"
  echo "*"
fi

sync

loadlist=`cat /proc/modules | ( \
  while read lm; do \
    set -- $lm; \
    loadlist="$loadlist $1"; \
  done  ; echo $loadlist )`

( cd $target_dir ;

inslist=""
children_pids=""

cleanup () {

    if test \! "x$children_pids" = x; then
       $sudo kill -SIGINT $children_pids >& /dev/null
       children_pids=""
       sleep 1
    fi
    if test \! "x$inslist" = x; then
       for mod in $inslist ; do
	  test $verbose = 1 && echo "+ $rmmod $mod"
	  $sudo $rmmod $mod
       done
       inslist=""
    fi
}

trap cleanup SIGINT

while test -n "$target_deps" ; do
  mod=`echo $target_deps|cut -d+ -f1`
  target_deps=`echo $target_deps|cut -s -d+ -f2-`
  if test -h $xeno_moddir/xeno_$mod$modext; then
     # Substitute the symlink with the target name since
     # new modutils (>= 2.5.48) will use the actual name.
     mod=`file -b $xeno_moddir/xeno_$mod$modext|sed -e "s,.*xeno_\([a-z0-9A-Z]*\)$modext.*,\1,"`
  fi
  if `echo $loadlist | grep -vq "\\bxeno_$mod\\b"`; then
     # If we cannot find the module in our install dir, try Linux's
     # one.
     if test -r $xeno_moddir/xeno_$mod$modext; then
        test $verbose = 1 && echo "+ $insmod $xeno_moddir/xeno_$mod$modext"
        $sudo $insmod $xeno_moddir/xeno_$mod$modext
	if test $? = 0 ; then
           inslist="xeno_$mod $inslist"
           loadlist="$loadlist $mod"
	else
	   echo "ERROR: cannot load $xeno_moddir/xeno_$mod$modext"
	   break
        fi
     elif `$modprobe -n $mod >& /dev/null`; then
        test $verbose = 1 && echo "+ $modprobe $mod"
        $sudo $modprobe $mod
        inslist="$mod $inslist"
        loadlist="$loadlist $mod"
     fi
  fi
done

while test -n "$target_info" ; do
  action=`echo $target_info|cut -d';' -f1`
  target_info=`echo $target_info|cut -s -d';' -f2-`
  set -- $action

  case "$1" in

    push)

	mod=`basename $2 $modext`
        if test -r $user_moddir/$mod$modext; then
           modpath="$user_moddir/$mod"
        else
           modpath="$mod"
        fi
	if `echo $loadlist | grep -vq "\\b$mod\\b"`; then
	   test $verbose = 1 && echo "+ $insmod $modpath$modext"
	   $sudo $insmod $modpath$modext
	   if test $? = 0; then
              loadlist="$loadlist $mod"
	      inslist="$mod $inslist"
	   else
	      echo "ERROR: cannot load $modpath$modext"
	   fi
	fi
	;;

    pop)

	shift
	if test "x$*" = x; then
           rmlist=`echo $inslist | cut -s -f1 -d' '`
        else
           rmlist=$*
	fi
        _inslist="$inslist"
	if test \! "x$rmlist" = x; then
           for mod in $rmlist ; do
	      test $verbose = 1 && echo "+ $rmmod $mod"
	      $sudo $rmmod $mod && _inslist=`echo $_inslist | sed -e "s,$mod,,g"`
           done
        inslist="$_inslist"
	fi
	;;

    popall|flush)

        cleanup
	;;

    *)

        case "$1" in
	  exec|spawn) shift ;;
	  klog) set -- \! tail -f /var/log/messages ;;
	esac
	e=`echo $* | sed -e "s,^[$spc]*![$spc]*\\(.*\\)$,\\1,"`
        test "$e" = "$*" && suflag= || suflag=$sudo
	set -- $e
	e=`echo $* | sed -e "s,\\(.*\\)&[$spc]*$,\\1,"`
        test "$e" = "$*" && waitflag=1 || waitflag=0
	set -- $e
	test $verbose = 1 && echo "+ spawning command ($* $cmdargs)"
	if test $waitflag = 1; then
           $suflag $* $cmdargs
        else
           $suflag $* $cmdargs &
	   children_pids="$! $children_pids"
	fi
	;;
  esac

done )

exit 0
